package com.persion.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.poi.excel.ExcelFileUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.persion.common.core.domain.entity.SysUser;
import com.persion.common.core.redis.RedisCache;
import com.persion.common.utils.DateUtils;
import com.persion.common.utils.SecurityUtils;
import com.persion.common.utils.ip.AddressUtils;
import com.persion.common.utils.ip.IpUtils;
import com.persion.common.utils.poi.ExcelUtil;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.common.Credential;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.persion.common.annotation.Anonymous;
import com.persion.common.config.RuoYiConfig;
import com.persion.common.core.domain.AjaxResult;
import com.persion.common.utils.StringUtils;
import com.persion.common.utils.file.FileUploadUtils;
import com.persion.common.utils.file.FileUtils;
import com.persion.common.utils.sign.Base64;
import com.persion.domain.Opeople;
import com.persion.dto.Params;
import com.persion.framework.config.ServerConfig;
import com.persion.service.OpeopleService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.persion.vo.IdCardResultVO;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * 老人个人信息(Opeople)表控制层
 *
 * @author WangFK
 * @since 2024-01-23 20:13:33
 */
@RestController
@Slf4j
@RequestMapping("/manage/older")
public class OpeopleController {
    /**
     * 服务对象
     */
    @Resource
    private OpeopleService opeopleService;
    @Resource
    private ServerConfig serverConfig;
    @Resource
    private RedisCache redisCache;



    @Anonymous
    @PostMapping("/login")
    public AjaxResult login(@RequestBody Opeople opeople, HttpServletRequest request) {
        String opPhone = opeople.getOpPhone();
        if (ObjectUtil.isEmpty(opPhone)||ObjectUtil.isEmpty(opeople.getOpPassword())||!PhoneUtil.isPhone(opPhone)){
            return AjaxResult.warn("请按规范填写");
        }
        String key = "care-persion:opeople:phone:"+opPhone;
        Opeople value = Convert.convert(Opeople.class, redisCache.getCacheObject(key));
        if (!ObjectUtil.isEmpty(value)){
            return AjaxResult.success(value);
        }
        LambdaQueryWrapper<Opeople> lqw = new LambdaQueryWrapper<Opeople>().eq(Opeople::getOpPhone, opPhone);
        Opeople one = opeopleService.getOne(lqw);
        if (ObjectUtil.isEmpty(one)){
            return AjaxResult.warn("用户不存在，请注册");
        }
        if (!SecurityUtils.matchesPassword(opeople.getOpPassword(),one.getOpPassword())){
            return AjaxResult.error("密码或账号不正确");
        }
        opeopleService.update(new LambdaUpdateWrapper<Opeople>()
                        .eq(Opeople::getOpId,one.getOpId())
                .set(Opeople::getLoginIp,IpUtils.getIpAddr(request))
                .set(Opeople::getLoginAddress, AddressUtils.getRealAddressByIP(IpUtils.getIpAddr(request)))
                .set(Opeople::getLoginData,DateUtil.now()));
        redisCache.setCacheObject(key,one,30, TimeUnit.MINUTES);
        return AjaxResult.success(one);
    }

    @PostMapping("/export")
    public void export(HttpServletResponse response, Params params) {
        AjaxResult list = list(params);
        Object rows = list.get("rows");
        List<Opeople> opeopleList = JSONUtil.toList(JSONUtil.toJsonStr(rows), Opeople.class);
        ExcelUtil<Opeople> util = new ExcelUtil<Opeople>(Opeople.class);
        util.exportExcel(response, opeopleList, "老人数据");
    }

    /**
     * 上传身份证并识别ORC
     *
     * @param file
     * @return
     * @throws IOException
     */
    @Anonymous
    @PostMapping("/IDCardOCR")
    public AjaxResult uploadFileIDCardOCR(MultipartFile file) throws Exception {
        String SecretId = "AKIDh040nR5hCVfpwAIHA0GXkxX6b5UijV5U";
        String SecretKey = "ILBm8Fc7cx50hAUcdeAcx9JWdeYJtIWe";
        try {
            Credential cred = new Credential(SecretId, SecretKey);
            OcrClient client = new OcrClient(cred, "ap-beijing");
            IDCardOCRRequest req = new IDCardOCRRequest();
            String encode = Base64.encode(file.getBytes());
            req.setImageBase64(encode);
            req.setCardSide("FRONT");
            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            IDCardOCRResponse resp = client.IDCardOCR(req);
            // 输出json格式的字符串回包
            IdCardResultVO vo = JSONUtil.toBean(IDCardOCRResponse.toJsonString(resp), IdCardResultVO.class);
            AjaxResult ajax = getUploadFile(file);
            String birth = vo.getBirth();
            Date date = DateUtil.parse(birth, "yyyy/MM/dd");
            int opAge = DateUtil.thisYear() - DateUtil.year(date);
            ajax.put("IdCardResultVO", vo)
                    .put("opAge", opAge);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    private AjaxResult getUploadFile(MultipartFile file) throws IOException {
        // 上传文件路径
        String filePath = RuoYiConfig.getUploadPath();
        // 上传并返回新文件名称
        String fileName = FileUploadUtils.upload(filePath, file);
        String url = serverConfig.getUrl() + fileName;
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", url);
        ajax.put("fileName", fileName);
        ajax.put("newFileName", FileUtils.getName(fileName));
        ajax.put("originalFilename", file.getOriginalFilename());
        return ajax;
    }


    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody Opeople opeople) {
        LambdaUpdateWrapper<Opeople> lqw = new LambdaUpdateWrapper<>();
        lqw.eq(Opeople::getOpId, opeople.getOpId())
                .set(Opeople::getOpStatus, opeople.getOpStatus());
        return opeopleService.update(lqw) ? AjaxResult.success() : AjaxResult.warn("修改状态失败");
    }

    /**
     * 分页查询
     *
     * @return com.persion.common.core.domain.AjaxResult
     * @Author WangFK
     * @Date 2024/1/24 9:22
     * @Param [params]
     **/
    @GetMapping("/list")
    public AjaxResult list(Params params) {
        Page<Opeople> opeoplePage = new Page<Opeople>(params.getPageNum(), params.getPageSize());
        LambdaQueryWrapper<Opeople> lqw = new LambdaQueryWrapper<>();
        String search = params.getSearch();
        String opSex = params.getOpSex();
        String opStatus = params.getOpStatus();
        String opBirthday = params.getOpBirthday();
        lqw.like(!StringUtils.isEmpty(search), Opeople::getOpName, search).or()
                .like(!StringUtils.isEmpty(search), Opeople::getOpAge, search).or()
                .like(!StringUtils.isEmpty(search), Opeople::getOpNative, search).or()
                .like(!StringUtils.isEmpty(search), Opeople::getOpAddress, search).or()
                .like(!StringUtils.isEmpty(search), Opeople::getLoginAddress, search).or()
                .like(!StringUtils.isEmpty(search), Opeople::getOpPhone, search).or()
                .like(!StringUtils.isEmpty(search), Opeople::getOpCard, search)
                .eq(!StringUtils.isEmpty(opSex), Opeople::getOpSex, opSex)
                .eq(!StringUtils.isEmpty(opStatus), Opeople::getOpStatus, opStatus)
                .eq(!StringUtils.isEmpty(opBirthday), Opeople::getOpBirthday, opBirthday);
        opeoplePage = opeopleService.page(opeoplePage, lqw);
        List<Opeople> records = opeoplePage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success("暂无信息");
        }
        return AjaxResult.success()
                .put("rows", records)
                .put("total", records.size());
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public AjaxResult selectOne(@PathVariable Serializable id) {
        return AjaxResult.success(opeopleService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param opeople 实体对象
     * @return 新增结果
     */
    @PostMapping
    @Anonymous
    public AjaxResult insert(@RequestBody Opeople opeople) {
        if (ObjectUtil.isEmpty(opeople.getOpIdcard())) {
            return AjaxResult.error("请重新上传身份证");
        }
        if (ObjectUtil.isEmpty(opeople.getOpPhone()) || !PhoneUtil.isPhone(opeople.getOpPhone())) {
            return AjaxResult.error("请重新输入手机号");
        }
        if (!ObjectUtil.isEmpty(opeople.getOpId())) {
            return update(opeople);
        }
        LambdaQueryWrapper<Opeople> lqw = new LambdaQueryWrapper<Opeople>().eq(Opeople::getOpPhone, opeople.getOpPhone());
        List<Opeople> list = opeopleService.list(lqw);
        if (ObjectUtil.isNotEmpty(list)) {
            return AjaxResult.error("手机号：" + opeople.getOpPhone() + "重复!");
        }

        // 密码默认 888888888
        if (ObjectUtil.isEmpty(opeople.getOpPassword())) {
            opeople.setOpPassword(SecurityUtils.encryptPassword("88888888"));
        }
        // 加密身份证号
        opeople.setOpIdcard(SecurityUtils.encryptPassword(opeople.getOpIdcard()));
        try {
            opeopleService.save(opeople);
        } catch (Exception e) {
            return AjaxResult.error("姓名：" + opeople.getOpName() + "重复!");
        }
        return AjaxResult.success("添加成功",opeople);
    }

    /**
     * 修改数据
     *
     * @param opeople 实体对象
     * @return 修改结果
     */
    @PutMapping
    public AjaxResult update(@RequestBody Opeople opeople) {
        if (!opeople.getOpPhone().equals(opeopleService.getById(opeople.getOpId()).getOpPhone())) {
            LambdaQueryWrapper<Opeople> lqw = new LambdaQueryWrapper<Opeople>().eq(Opeople::getOpPhone, opeople.getOpPhone());
            List<Opeople> list = opeopleService.list(lqw);
            if (ObjectUtil.isNotEmpty(list)) {
                return AjaxResult.error("手机号：" + opeople.getOpPhone() + "重复!");
            }
        }
        if (!StringUtils.containsAny(".", opeople.getOpIdcard())) {
            // 加密身份证号
            opeople.setOpIdcard(SecurityUtils.encryptPassword(opeople.getOpIdcard()));
            try {
                opeopleService.updateById(opeople);
            } catch (Exception e) {
                return AjaxResult.error("姓名：" + opeople.getOpName() + "重复!");
            }
        }
        return opeopleService.update(new LambdaUpdateWrapper<Opeople>().eq(Opeople::getOpId, opeople.getOpId()).set(Opeople::getOpPhone, opeople.getOpPhone())) ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
    }

    /**
     * 删除数据
     *
     * @param id 主键结合
     * @return 删除结果
     */
    @DeleteMapping("{id}")
    public AjaxResult delete(@PathVariable Serializable id) {
        return opeopleService.removeById(id) ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }
}

